package com.beiding.natgo.server;

import com.beiding.natgo.common.Exe;
import com.beiding.natgo.common.Message;
import lombok.extern.slf4j.Slf4j;

import javax.websocket.Session;
import java.util.*;

@Slf4j
public class SessionManager {

    private Map<String, SessionHolder> sessionHolderMap = new HashMap<>();

    private Set<Integer> forbiddenPorts = new HashSet<>();

    private Map<Integer, Set<String>> allowIpMap = new HashMap<>();

    private Timer checker;

    public void start() {
        checker = new Timer();
        //二十秒检查一次心跳
        checker.schedule(new TimerTask() {
            @Override
            public void run() {
                try {
                    log.info("执行心跳检测");
                    Set<String> set = sessionHolderMap.keySet();
                    long currentTimeMillis = System.currentTimeMillis();
                    List<String> removeIds = new ArrayList<>();
                    for (String id : set) {
                        SessionHolder sessionHolder = sessionHolderMap.get(id);
                        long lastHeartBeat = sessionHolder.getLastHeartBeat();
                        long time = currentTimeMillis - lastHeartBeat;
                        if (time >= 20000) {
                            removeIds.add(id);
                        } else {
                            //   log.info("时间 {}",time);
                        }
                    }
                    for (String removeId : removeIds) {
                        SessionHolder sessionHolder = sessionHolderMap.get(removeId);
                        if (sessionHolder != null) {
                            log.info("剔除无效连接 port={}", sessionHolder.getPort());
                            Exe.submit(() -> {
                                remove(sessionHolder.getSession());
                            });
                        }
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, 0, 10 * 1000);
    }

    public void stop() {
        checker.cancel();
    }

    public void forbiddenPort(Integer port, Long time) {
        forbiddenPorts.add(port);
        if (time != null) {
            checker.schedule(new TimerTask() {
                @Override
                public void run() {
                    removeForbiddenPort(port);
                }
            }, time);
        }
    }

    public void removeForbiddenPort(Integer port) {
        forbiddenPorts.remove(port);
    }

    public void put(Session session) {
        sessionHolderMap.put(session.getId(), new SessionHolder(session));
    }

    //websocket消息是有序的 可靠的
    public void handleMessage(Session session, Message message) {
        try {
            if (message.getType() == 1) {//收到消息
                /*System.out.println("服务端消息内容========");
                System.out.println(new String(message.byteData()));
                System.out.println("==========");*/
                sessionHolderMap.get(session.getId()).writeData(message.getChanelId(), message.byteData());
            } else if (message.getType() == 10) {//客户端心跳包
                log.info("收到心跳包");
                sessionHolderMap.get(session.getId()).heartBeat();
            } else if (message.getType() == 2) {//初始化端口监听
                initPort(session.getId(), message.getPort());
            }
            if (message.getType() == 7) {//关闭通道
                sessionHolderMap.get(session.getId()).closeChanel(message.getChanelId());
            } else if (message.getType() == 8) {//创建新连接成功
                sessionHolderMap.get(session.getId()).createChanelSuccess(message.getChanelId());
            } else if (message.getType() == 5) {//创建新连接失败
                sessionHolderMap.get(session.getId()).createChanelFail(message.getChanelId());
            } else if (message.getType() == 6) {//对方错误
                log.error(message.getMsg());
            }
        } catch (Exception e) {
            remove(session);
            e.printStackTrace();
        }
    }

    public void initPort(String id, Integer port) {
        SessionHolder sessionHolder = sessionHolderMap.get(id);
        if (sessionHolder != null) {
            if (forbiddenPorts.contains(port)) {//如果被禁用
                Message message = new Message();
                message.setType(3);
                message.setMsg("端口被禁用");
                sessionHolder.send(message);
            } else {
                try {
                    sessionHolder.initPort(port);
                } catch (Exception e) {
                    e.printStackTrace();
                    Message message = new Message();
                    message.setType(3);
                    message.setMsg(e.getMessage());
                    sessionHolder.send(message);
                }
            }
        }
    }

    public void remove(Session session) {
        SessionHolder sessionHolder = sessionHolderMap.remove(session.getId());
        if (sessionHolder != null) {
            sessionHolder.close();
        }
    }

    public void confAllIp(Integer port, Set<String> ips) {
        if (ips == null || ips.size() == 0) {

        }
    }

    public Map<String, SessionHolder> getSessionHolderMap() {
        return sessionHolderMap;
    }

    public Set<Integer> getForbiddenPorts() {
        return forbiddenPorts;
    }

    public Map<Integer, Set<String>> getAllowIpMap() {
        return allowIpMap;
    }
}
